[ Mega Script
Archive ] [ Readme's
] [ HTTP
Cookie Library ]
- Copyright and Header
- Overview
- cookie.lib Configuration
- Using this Library in your CGI
script
- Character Translation Information
- Any Examples Available?
- Other Cookie Resources
- History
##############################################################################
# HTTP Cookie Library Version 2.1 #
# Copyright 1996 Matt Wright mattw@worldwidemart.com #
# Created 07/13/96 Last Modified 12/23/96 #
# Scripts Archive at: http://www.worldwidemart.com/scripts/ #
# Parts of Code Contributed by Jeff Carnahan (http://terminalp.com/scripts/) #
##############################################################################
# If you run into any problems while trying to configure this script, help #
# is available. The steps you should take to get the fastest results, are: #
# 1) Read this file thoroughly #
# 2) Consult the Matt's Script Archive Frequently Asked Questions: #
# http://www.worldwidemart.com/scripts/faq/ #
# 3) If you are still having difficulty installing this script, send #
# e-mail to: scripts-help@tahoenet.com #
# Include any error messages you are receiving and as much detail #
# as you can so we can spot your problem. Also include the variable#
# configuration block that is located at the top of the script. #
# #
# Hopefully we will be able to help you solve your problems. Thank you. #
##############################################################################
# COPYRIGHT NOTICE #
# Copyright 1996 Matthew M. Wright All Rights Reserved. #
# #
# HTTP Cookie Library may be used and modified free of charge by anyone so #
# long as this copyright notice and the comments above remain intact. By #
# using this code you agree to indemnify Matthew M. Wright from any #
# liability that might arise from it's use. #
# #
# Selling the code for this program without prior written consent is #
# expressly forbidden. In other words, please ask first before you try and #
# make money off of my program. #
# #
# Obtain permission before redistributing this software over the Internet or #
# in any other medium. In all cases copyright and header must remain intact #
##############################################################################
HTTP Cookie Library is a Perl 4 and 5
compatible library which allows you to easily
use Persistent Client State HTTP Cookies by
allowing you to get the cookies from the
environment, prepare cookies, set cookies,
change the expiration date, domain and path
all with easy subroutine calls.
Version 2.0 and 2.1 contain many changes,
including the ability to compress multiple
cookies into one, the elimination of the
&PrepareCookies subroutine, and fixes
allowing you to set more than one cookie at a
time. The addition of character URL-encoding
and the fixing of a scoping bug brought on by
localizing the global variables used in this
script are new to version 2.1.
NOTE: Anyone who
used 2.0 and &UnCompressCookies
should now change all references from
&UnCompressCookies to
&GetCompressedCookies. The calls to
these routines are the same, however the
name has been changed.
For more information on Cookies, and to
see the preliminary specifications of
Persistent Client State HTTP Cookies to which
this library conforms, visit
http://www.netscape.com/newsref/std/cookie_spec.html
There are three files included with this
script:
- README - This file; includes detailed
installation instructions.
- cookie.lib - The Perl script which
generates the random phrase and
displays it on your web page.
- ccounter.pl - An example of how to
use this library.
The cookie.lib perl library is not a
stand-alone CGI script. It is meant to be
used in conjunction with a script that you
build. It's only purpose is to facilitate the
usage of client side persistent HTTP cookies.
This means, in order to use this library, you
should always have the following line in your
script somewhere:
require '/path/to/cookie.lib';
This will then tell Perl to retrieve this
file and include it's code and subroutines in
your script. Nonetheless, there are some
variables which you can modify in the
cookie.lib file before you place it on your
system. All of these variables can be
modified through special subroutines in
cookie.lib so it is not necessary to edit any
of them.
- This program contains three variables
which can be modified in the library, to
make it easier to use on your system.
They can also be set through calling
subroutines, which is explained in:
'Using this Library in Your CGI Script,'
or by setting them in your main script,
as they are local variables which can be
modified. The subroutines provide checks
to make sure the value is valid.
- $Cookie_Exp_Date
= '';
- This variable defines the
expiration date of your cookie.
When this date arrives the
browser will ask the user if they
want to delete the cookie, and
that it is ok to do so. This date
must always be represented as:
Wdy, DD-Mon-YYYY HH:MM:SS GMT
and always has to be in GMT
time. An example would be: Wed,
09-Nov-1999 00:00:00 GMT. By
default, if this is not filled
in, the browser will delete the
cookie when the session ends.
Also see &SetCookieExpDate.
- $Cookie_Path
= '';
- This path defines where under
your domain the cookies should be
sent. For instance, if your URL
is: http://domain.xxx/your_dir/,
there is no reason for the
browser to send the Cookie header
to the base domain name.
Therefore, you would set this to
'/your_dir'; However, because
this can be set through the
script, set it to whatever
directory will use this most
often or whichever directory you
want as default. If nothing is
placed here, the default will be
assumed to be the script or page
which created the cookie. Also
see &SetCookiePath.
- $Cookie_Domain
= '';
- This defines the base domain to
which the browse passes the
cookie. If you have a domain:
www.host.xxx, your.host.xxx and
host.xxx, which all will use
this, you would set this variable
to: '.host.xxx'; The following is
an excerpt from the Netscape
Preliminary Specifications of
Persistent Client State HTTP
Cookies:
"Only hosts
within the specified domain can
set a cookie for a domain and
domains must have at least two
(2) or three (3) periods in them
to prevent domains of the form:
".com",
".edu", and
"va.us". Any domain
that fails within one of the
seven special top level domains
listed below only require two
periods. Any other domain
requires at least three. The
seven special top level domains
are: "COM",
"EDU", "NET",
"ORG", "GOV",
"MIL", and
"INT"."
- $Secure_Cookie
= '0';
- This defines whether or not you
want to restrict the transmission
of the cookie to a secure server.
If this flag is set to '1', by
default the cookies you create
will only be sent to secure
servers by the client. This can
also be changed through
&SetSecureCookie.
- @Cookie_Encode_Chars
= ('\%', '\+', '\;', '\,', '\=',
'\&', '\:\:', '\s');
- This defines the order in which
the special characters should be
encoded. More info can be found
in section entitled 'Character
Translation Information'.
- %Cookie_Encode_Chars
= ('\%', '%25',
'\+',
'%2B',
'\;',
'%3B',
'\,',
'%2C',
'\=',
'%3D',
'\&', '%26',
'\:\:', '%3A%3A',
'\s',
'+');
- This associative array defines
the characters to be translated
as the keys, which can be
referred to as:
$Cookie_Encode_Chars{key} and the
values which these characters
should be translated into. More
info can be found in section
entitled 'Character Translation
Information'.
- @Cookie_Decode_Chars
= ('\+', '\%3A\%3A', '\%26',
'\%3D', '\%2C', '\%3B', '\%2B',
'\%25');
- This defines the order in which
the special characters should be
decoded. More info can be found
in section entitled 'Character
Translation Information'.
- %Cookie_Decode_Chars
= ('\+', ' ',
'\%3A\%3A', '::',
'\%26', '&',
'\%3D', '=',
'\%2C', ',',
'\%3B', ';',
'\%2B', '+',
'\%25', '%');
- This associative array defines
the characters to be translated
as the keys, which can be
referred to as:
$Cookie_Decode_Chars{key} and the
values which these characters
should be decoded into. More info
can be found in section entitled
'Character Translation
Information'.
- HTTP Cookie Library is not meant as a
standalone CGI script. It must be used in
conjunction with other scripts you have
written, and provides a basic outline and
easy subroutines which makes implementing
the cookies into your perl program easy.
Also,
to give cookies to the user, the browser
must be pointed to the CGI application or
the CGI application must be imbedded in
the HTML document through Server Side
Includes or other technology, such as
JavaScript. If you choose the JavaScript
path, some browsers which support cookies
won't be able to receive them and
JavaScript users have no use for this
library as it is only compatible in Perl
scripted CGI applications.
Near the top of your Perl CGI
script (or before you make the first
call to a subroutine which is in
cookie.lib), you will need to include
the line:
require '/path/to/cookie.lib';
If you place the cookie.lib in the
same directory as your CGI script, or
in a path which is defined in @INC,
you can call it with:
require 'cookie.lib';
Now that you have required the
library, all of the subroutines which
this script contains can be used in
your CGI Perl script. Here's is a
summary of them, what they do and how
to call them:
- &GetCookies('cookie_name1',...,'cookie_namen');
- This function can be called
as simply &GetCookies, or
using arguments such as
&GetCookies('cookie1','cookie2').
Calling it without arguments
means that it will return a
'1' if cookies are found, a 0
if they are not. This is
useful, so that you can
perform function like:
if (&GetCookies) {
# Successful Code Here;
}
else {
# Give them a Cookie Here;
}
In the above circumstance,
if cookies are found, the
successful code gets
executed. Otherwise, you can
give them a cookie. The
&GetCookies subroutine
then takes the cookies from
the environment and places
them in an associative array.
This array is %Cookies. So if
you have set a cookie named
'visit' with a value which
contains whatever you set it
for, then you would obtain
this value by using the
scalar variable
$Cookies{'visit'}.
Now, let's say that a lot
of cookies are set for your
base domain and path. They
would all get included in the
return if you didn't specify
arguments for
&GetCookies. For
instance, in the above
example, since
&GetCookies would return
a value of '1' if any cookies
are set, that could mess up
this script, if all we want
to know is if the visit
cookie is set. Therefore, we
would change the above
program to only need to
'visit' cookie:
if (&GetCookies('visit')) {
# Successful Code Here;
}
else {
# Give them a Cookie Here;
}
Now, only the
$Cookies{'visit'} scalar will
be set and if it is not
&GetCookies will return a
0 and the else { } statement
will be executed.
You can check for multiple
cookies to be set by
&GetCookies('name1',
'name2','etc...'); However
this will return a true value
(1) if any of those cookies
are set. You can get around
this by calling them one at a
time, although this is
tedious.
If you have compressed
your cookies with
&SetCompressedCookies,
you will need to look into
the &GetCompressedCookies
routine to do what
&GetCookies does.
- &SetCookieExpDate('Wdy,
DD-Mon-YYYY HH:MM:SS GMT');
- By default in the script, the
cookie is set to expire when
the browser session ends. If
you wish for the cookie to
expire at a later date, then
all you have to do is change
the date by calling
&SetCookieExpDate with an
argument containing the new
date. The new date must be in
the format as shown above, or
it will not set right. The
following is an example:
&SetCookieExpDate('Wed, 09-Nov-1999 00:00:00 GMT');
If your date does not
match a regular expression
which checks to see if it is
valid, it will return a 0. So
it you catch the value, you
can do:
if (&SetCookieExpDate('Wdy, DD-Mon-YYYY HH:MM:SS GMT')) {
# Continue here.
}
else {
# Do Error Stuff Here. &SetCookieExpDate failed.
}
For any cookies which you
wish to be able to detect if
the user closes the browser's
session and then re-opens it,
you will need to set this to
a specific date.
The $Cookie_Exp_Date
variable can also be changed
at the top of cookie.lib, or
at any point inside of the
perl script which required
cookie.lib, simply with the
statement:
$Cookie_Exp_Date = 'Wdy, DD-Mon-YYYY HH:MM:SS GMT';
The subroutine is provided
to check the syntax of your
date.
- &SetCookiePath('/path');
- By default, this is set to
the path of the script or web
page which sets the cookie,
so unless this has been set
differently in cookie.lib to
contain a value, you need not
call this function. However,
if you wish for those values
to be passed to other scripts
under the same domain, you
will need to have this set to
that path of the URL. For
instance, if I only want my
cookies passed to URLs which
are at least:
http://www.worldwidemart.com/scripts,
I would call this function
as:
&SetCookiePath('/scripts');
You can also set the
cookie path with the
statement:
$Cookie_Path = '/path/you/want/to/set';
You can place this
statement anywhere in your
Perl programs after you have
required the cookie.lib
library.
- &SetCookieDomain('.host.xxx');
- If the value of your desired
domain suffix (.host.xxx) was
assigned a different value as
default, you can change this
by placing a domain name in
the call to
&SetCookieDomain. Most of
the time you shouldn't have
to worry about this. Below
are the rules which this
script follows, taken
directly from Netscape
documentation:
"Only
hosts within the specified
domain can set a cookie for a
domain and domains must have
at least two (2) or three (3)
periods in them to prevent
domains of the form:
".com",
".edu", and
"va.us". Any domain
that fails within one of the
seven special top level
domains listed below only
require two periods. Any
other domain requires at
least three. The seven
special top level domains
are: "COM",
"EDU",
"NET",
"ORG",
"GOV",
"MIL", and
"INT"."
The $Cookie_Domain can
also be set using the
statemement:
$Cookie_Domain = 'host.xxx';
You can place this
statement anywhere in your
Perl programs after you have
required the cookie.lib
library.
- &SetSecureCookie('0'
|| '1');
- This defines whether or not
this cookie should be relayed
only to secure servers.
Calling
&SetSecureCookie('1');
means that clients will only
pass those cookies you have
set to secure servers.
Calling
&SetSecureCookie('0');
means the cookies will be
transferred whenever the path
and domain are correct,
regardless of security
issues. Here is an excerpt
from Netscape specs:
"If
a cookie is marked secure, it
will only be transmitted if
the communications channel
with the host is a secure
one. Currently this means
that secure cookies will only
be sent to HTTPS (HTTP over
SSL) servers. If secure is
not specified, a cookie is
considered safe to be sent in
the clear over unsecured
channels."
You can also change the
value of $Secure_Cookie
through a statement:
$Secure_Cookie = 1;
or
$Secure_Cookie = 0;
You can place this
statement anywhere in your
Perl programs after you have
required the cookie.lib
library.
- &SetCookies('cookie_name1',
'cookie_value1', ...,
'cookie_namen',
'cookie_valuen');
- This function has been
completely changed since
Version 1.1.1, except for the
fact that it actually does
set the cookies. There is no
longer a call to
&PrepareCookies, but
rather &SetCookies does
it all.
If you wish to set
the cookies name and email,
and have the values of these
cookies in the variables
$name and $email, you would
set them with the following
code:
print "Content-type: text/html\n";
&SetCookies('name',"$name",'email',"$email");
print "\n";
The first line prints out
the text/html header, with
one new line following it,
rather than two, since the
header sent to the browser is
not yet complete. Then, our
call to &SetCookies is
made. This call will send two
Set-Cookie: headers to the
browser and set both of the
cookies for us.
You can send as many
cookies to this subroutine as
you wish to set. Browsers do
have a limit though, so if
you are setting multiple
cookies, it is suggested that
you look into the
&SetCompressedCookies
subroutine.
- &SetCompressedCookies('compressed_cookie_name',
'cookie_name1',
'cookie_value1', ...,
'cookie_namen',
'cookie_valuen');
- This subroutine does almost
the same thing that
&SetCookies does, but
instead it takes one extra
argument. You call it with
the name of the compressed
cookie which you wish to set
and then the name/value pairs
of of the cookies which you
wish to compress. This
subroutine doesn't actually
compress cookies, but it
takes multiple cookies and
strings them together, so to
the browser they appear as
one. The = signs are
converted into :: and the
name/value pairs are
separated from each other by
&, however there is no
need to change these
characters before hand, as
they will be translated back
when uncompressed.
You may
be saying, why should I
bother compressing cookies
when it takes extra work? I
can just set 50 cookies all
for different things. The
main reason is, that
according to Netscape's
specification:
"There are
limitations on the number of
cookies that a client can
store at any one time. This
is a specification of the
minimum number of cookies
that a client should be
prepared to receive and
store.
- 300 total cookies
- 4 kilobytes per
cookie, where the name
and the value combine to
form the 4 kilobyte
limit.
- 20 cookies per
server or domain. (note
that completely specified
hosts and domains are
treated as separate
entities and have a 20
cookie limitation for
each, not combined)
Servers should not expect
clients to be able to exceed
these limits. When the 300
cookie limit or the 20 cookie
per server limit is exceeded,
clients should delete the
least recently used cookie.
When a cookie larger than 4
kilobytes is encountered the
cookie should be trimmed to
fit, but the name should
remain intact as long as it
is less than 4
kilobytes."
This also means that it is
up to you to check and make
sure that your compressed
cookie will not take more
than 4KB. This is not going
to be a common problem most
likely, though, as 4KB is
4,000 characters, which if
typed out on a common 80
column screen is about 50
lines, or almost a full page
of text. The 20 cookie limit
on one server name is
definitely a common problem,
and this helps save some of
this space. As cookies become
more common, clients may
start reaching the 300 cookie
maximum more rapidly as well.
Let's take the example
from &SetCookies above,
with the name and email
cookies we wish to set. Now,
rather than taking up two
cookies, we can set one
cookie named user, which will
contain the information
stored in the name and email
cookies. To do this, make you
make a call like:
print "Content-type: text/html\n";
&SetCompressedCookies('user','name',$name,'email',$email);
print "\n";
This sets a cookie named
user which contains the
cookies name and email. In
order to uncompress this
cookie, you need to use the
&GetCompressedCookies
subroutine explained below.
It acts much like
&GetCookies.
WARNING: It is a good idea
not to set the compressed
cookie name equal to the name
of a cookie being stored in
the compressed cookie. It can
mess things up.
- &GetCompressedCookies('compressed_cookie_name',
'cookie_name1', ...,
'cookie_namen');
- This subroutine works in
almost the same way as
&GetCookies, except that
it needs the name of the
compressed cookie first,
followed by the names of the
cookies you wish to retrieve
out of the compressed cookie.
If this subroutine is called
with only the name of the
compressed cookie, it will
retrieve all values and place
them in the %Cookies array.
For
instance, if we were to take
the example used in
&SetCompressedCookies and
we needed to only get the
name of the user out of the
compressed cookie, we would
do something like:
&GetCompressedCookies('user','name');
Where 'user' was the name
of the cookie we specified to
be set when we compressed the
cookies and 'name' was one of
the cookies we compressed
into 'user'. The value of
name can not be retrieved
from $Cookies{'name'}.
Or if you wished to get
every cookie out of the
compressed cookie, you can
simply say:
&GetCompressedCookies('user');
And now $Cookies{'name'}
and $Cookies{'email'} are
set.
- Version 2.1 of the HTTP Cookie Library
introduces some simple character
URL-encoding which eases the use and
fixes some common problems with cookies.
Previously, cookies would often not be
set if they included spaces, semi-
colons, and a few other special
characters. There was also the problem
found if information contained two :: or
an & and you tried to compress the
cookies, because those two characters are
used for the compression sequence that
HTTP Cookie Library uses.
According to
Netscape's Persistent Client State HTTP
Specification:
"This string is a sequence
of characters excluding semi-colon,
comma and white space. If there is a
need to place such data in the name
or value, some encoding method such
as URL style %XX encoding is
recommended, though no encoding is
defined or required."
HTTP Cookie Library does use the URL
style %XX (also known as hex) encoding to
ensure that these characters are not lost
and that the cookie is set.
-
ccounter.pl, an example of
how to use some of the
features in this library
comes bundled with the
script. Hopefully the docs
have been written extensively
enough and the library
commented enough (this is the
most commented and
well-documented script at
MSA) that it should be fairly
easy to figure out.
You can find real-world
implementations of this
library listed at MSA in the
Scripts Around the World
section. The HTTP Cookie
Library page for this can be
found at:
http://www.worldwidemart.com/scripts/examples/cookielib.shtml
If you have used the
library, please let us know
so we can add it!
Version 2.1 - 12/19/96 - Changed the local() scope of global
variables because they weren't setting at
the top of the script right.
- 12/20/96 - Added URL-encoding to the cookies for the
characters: '%', '+', ':', ',', '=', '&',
'::', and space. More on this explained
in the section, 'Character Translation'.
- &UnCompressCookies changed to
&GetCompressedCookies, making more sense.
- 12/23/96 - &SetCookieExpDate fixed to allow a blank
date.
Version 2.0 - 11/28/96 - &SetCookieExpDate still not working right,
and finall fixed.
- &SetCompressedCookies and &UnCompressCookies
subroutines added so multiple cookies can be
set as one cookie and take up less room in
the cookies.txt file.
- &PrepareCookie replaced by changing
&SetCookies to do all of the work. This
subroutine now actually takes values and
sets them.
- Multiple cookied can be set now. A bug
existed before which wouldn't set all of
the cookies.
- Checking now done when setting cookie domain
so you can know if it will work. Based on
information in Netscape's Specifications.
Version 1.1.1 - 07/15/96 - Andy Kington
pointed out that the ExpDate Year should be
represented as YYYY instead of YY.
Version 1.1 - 07/14/96 - Added secure option and routines.
Version 1.0 - 07/14/96 - First Version Released
[
Mega Script Archive ]
|